package com.lzx.adx.report.util;

import com.alibaba.fastjson.JSONObject;
import com.lzs.adx.commmon.redis.RedisUtils;
import com.lzs.adx.commmon.utils.DateUtils;
import com.lzs.adx.commmon.utils.Result;
import com.lzx.adx.report.constant.RedisCacheKey;
import com.lzx.adx.report.dto.ReportDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

@Component
@Slf4j
public class DynamicRequestLimiter {


    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private RedisTemplate redisTemplate;




    public boolean shouldProcessRequest(String totalKey,String processedKey,double targetRadio) {
        //总的请求数+1
        long total = redisUtils.incr(totalKey,24);


        RedisAtomicLong processedRequests = new RedisAtomicLong(processedKey, redisTemplate.getConnectionFactory());
        long processed =  redisUtils.atomicGet(processedKey);


        // Check if the current processed-to-total ratio is below the target ratio.
        while ((double) processed / total < targetRadio) {
            //命中概率，就中值设置到缓存
            if (processedRequests.compareAndSet(processed, processed + 1)) {
                return true; // Successfully updated the processed count, process this request.
            }
            // If another thread updated the processed count in the meantime, retry the check.
            processed = processedRequests.get();
        }
        return false; // Do not process this request as we are above or at the target ratio.
    }


    /**
     * 扣回传统一逻辑
     * @param jsonObject
     * @param reportDTO
     * @return
     */
    public ResponseEntity<Result> getResultResponseEntity(JSONObject jsonObject, ReportDTO reportDTO){
        if(Objects.nonNull(jsonObject)) {
            Double per = jsonObject.getDouble("per");
            if (Objects.nonNull(per)) {
                String date = DateUtils.format(new Date(), "yyyyMMdd");
                String account_count_key=String.format(RedisCacheKey.account_count_key, reportDTO.getDspId(),date);
                String account_processed_key=String.format(RedisCacheKey.account_processed_key, reportDTO.getDspId(),date);
                if(!this.shouldProcessRequest(account_count_key, account_processed_key, per)){
                    log.info("流水号为 {} 超出了比例外，本次随机的值为{}，dspId为{}", reportDTO.getBizRequestId(), per, reportDTO.getDspId());
                    return ResponseEntity.ok(new Result());
                }
            }
        }else{
            log.info("流水号为 {} 未命中扣回传通过，dspId为{}", reportDTO.getBizRequestId(), reportDTO.getDspId());
        }
        return null;
    }


//    public static void main(String[] args) {
//        for (int i = 0; i < 10; i++) {
//            if (shouldProcessRequest(0.3)) {
//                System.out.println("Processing request: " + i);
//            } else {
//                System.out.println("Dropping request: " + i);
//            }
//        }
//    }
}
